package com.rfp.test.aes;

import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;


public class AesUtil
{
    public AesUtil(Key key, String offset) {
        this.key = key;
        this.offset = offset;
    }

    public AesUtil(String key, String offset) {
        this.key = new SecretKeySpec(Base64.getDecoder().decode(key), "AES");
        this.offset = offset;
    }

    // 密匙
    protected Key key;
    // 偏移量
    protected String offset;
    // 编码
    protected String encoding = "UTF-8";
    //算法
    protected String algorithm = "AES";
    // 默认的加密算法
    protected String cipherAlgorithm = "AES/ECB/PKCS5Padding";


    public String getEncoding() {
        return encoding;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    public String getAlgorithm() {
        return algorithm;
    }

    public void setAlgorithm(String algorithm) {
        this.algorithm = algorithm;
    }

    public String getCipherAlgorithm() {
        return cipherAlgorithm;
    }

    public void setCipherAlgorithm(String cipherAlgorithm) {
        this.cipherAlgorithm = cipherAlgorithm;
    }

    /**
     * 加密
     *
     * @param data
     * @return String
     * @throws Exception
     * @author tyg
     * @date 2018年6月28日下午2:50:35
     */
    public String encrypt(String data) throws Exception {
        return encrypt(data.getBytes(encoding));
    }

    public String encrypt(byte[] data) throws Exception {
        Cipher cipher = Cipher.getInstance(cipherAlgorithm);
        //SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("ASCII"), algorithm);
        IvParameterSpec iv = null;
        if (this.cipherAlgorithm.indexOf("ECB") == -1) {
            iv = new IvParameterSpec(offset.getBytes("ASCII"));//使用CBC模式，需要一个向量iv，可增加加密算法的强度
        }
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
        byte[] encrypted = cipher.doFinal(data);
        return Base64.getEncoder().encodeToString(encrypted);
    }

    /**
     * 解密
     *
     * @param data
     * @return String
     * @throws Exception
     * @author tyg
     * @date 2018年6月28日下午2:50:43
     */
    public String decrypt(String data) throws Exception {
        return decrypt(Base64.getDecoder().decode(data));
    }

    public String decrypt(byte[] data) throws Exception {
        Cipher cipher = Cipher.getInstance(cipherAlgorithm);
        //SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("ASCII"), algorithm);
        IvParameterSpec iv = null;
        if (this.cipherAlgorithm.indexOf("ECB") == -1) {
            iv = new IvParameterSpec(offset.getBytes("ASCII"));//使用CBC模式，需要一个向量iv，可增加加密算法的强度
        }
        cipher.init(Cipher.DECRYPT_MODE, key, iv);
        byte[] buffer = data;
        byte[] encrypted = cipher.doFinal(buffer);
        return new String(encrypted, encoding);//此处使用BASE64做转码。
    }

    public static String createKey() {

        try {
            // 生成key
            KeyGenerator keyGenerator;
            //构造密钥生成器，指定为AES算法,不区分大小写
            keyGenerator = KeyGenerator.getInstance("AES");
            //生成一个128位的随机源,根据传入的字节数组
            keyGenerator.init(128);
            //产生原始对称密钥
            Key secretKey = keyGenerator.generateKey();
            //获得原始对称密钥的字节数组
            byte[] keyBytes = secretKey.getEncoded();
            System.out.println("-----:" + new String(keyBytes));
            System.out.println(keyBytes.length);
            /*
            // key转换,根据字节数组生成AES密钥
            Key key = new SecretKeySpec(keyBytes, "AES");*/
            return Base64.getEncoder().encodeToString(keyBytes);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }

    }


    public static void main(String[] args) throws Exception {
        String key = "sII/rUbOHbbHc6WMCFJBGw==";
        AesUtil aesUtil = new AesUtil(key, null);
        String encryptResult = "MyOfyvAUYAjbo8WahNDGvVHDfLTJQ+e9ZDxOaDDPLvfB4lcyDvrXwZML2uRsebMswJyhTANsX6jw5Y+PkGcJj+CtSMLNMMBqrttjFH8SVM8IJ6gHqW5jgZljyCEq82DeOpM5wSlfO520A/Nt/SOncDm0xzimLv2RhPuhCOBlRWxKrGtSJDlFIvDHEKLqmEzFTV6J5CAq/5bZihUBDTGzOvexBEMkEZHZd8J0YbUxV+U=";
        System.out.println("demo解密的结果：" + aesUtil.decrypt(encryptResult));
    }

}


